# ==============================================================================
#
# autohome.pm
#
# Account maint auto_home functions
#
# $Id: autohome.pm,v 1.2 2005/08/31 10:48:52 dyoung2 Exp $
#
# Darren Young [darren.young@gsb.uchicago.edu]
#
# ==============================================================================
#
# ChangeLog
#
# $Log: autohome.pm,v $
# Revision 1.2  2005/08/31 10:48:52  dyoung2
#   * Added all functions from acctmaint.pl
#
# Revision 1.1  2005/08/31 10:45:39  dyoung2
#   * Initial version.
#
# ==============================================================================

my  $cvsid   = '$Id: autohome.pm,v 1.2 2005/08/31 10:48:52 dyoung2 Exp $';
my  @cvsinfo = split( ' ', $cvsid );
our $NAME    = File::Basename::basename($0);
our $VERSION = $cvsinfo[2];

# ------------------------------------------------------------------------------
#                             B E G I N
# ------------------------------------------------------------------------------
BEGIN {

    # Pragmas
    use strict;

    # "Standard" modules we use
    use FindBin;
    use Config::Simple;
    use lib "$FindBin::Bin/../lib";

    # Standard account maint modules to use
    use logging;
    use errcodes;
    use utils;
    
    # Modules that this module uses
    use amtools;
    use unixtools;

}


# ------------------------------------------------------------------------------ 
#                             V A R I A B L E S
# ------------------------------------------------------------------------------ 
our $LOGFILE    = "$FindBin::Bin/../log/acctmgr.log" unless($LOGFILE); 
our $CONFIGFILE = "$FindBin::Bin/../etc/acctmgr.cfg" unless($CONFIGFILE);


# ------------------------------------------------------------------------------
#                             C O N F I G   F I L E
# ------------------------------------------------------------------------------
our $CFG = new Config::Simple( filename => $CONFIGFILE ) or die "$!\n" unless($CFG);


# =============================================================================
# NAME        : _hasAutoHome
# DESCRIPTION : See if a user has an auto.home entry
# REQUIRES    : string(uname)
# RETURNS     : 0 on failure, 1 on success
# NOTES       : See comments for more information
# =============================================================================
sub _hasAutoHome ($) {
    my ($uname) = @_;
    my $name = "_hasAutoHome";
    my ( $package, $filename, $line ) = caller;
    logmsg("$name: entering with args @_");
    logmsg( "$name: called from package->$package, filename->$filename, line->$line" );

    my $found = 0;

    if ( ! defined($AUTOHOME) ) {
        logmsg("$name: $AUTOHOME isn't set");
        return(0);
    }

    logmsg("$name: checking $AUTOHOME entries for $uname");

    # open the auto.home file for read
    if ( open( AUTOHOME, "<$AUTOHOME" ) ) {
        logmsg("$name: opened auto.home file $AUTOHOME for read");
    } else {
        logmsg("$name: FAILED to open auto.home file $AUTOHOME for read ($!)");
        return(0);
    }

    while (<AUTOHOME>) {
        chomp();
        next if $_ =~ /#/;     # Skip comments
        next if $_ =~ /^$/;    # Skip blank lines

        # Grab the key/value from the input line (whitespace separates the
        # fields)
        my ( $m_uname, $m_mount ) = split( ' ', $_ );

        if ( $m_uname eq $uname ) {
            logmsg("$name: found entry for $m_uname as $m_mount");
            $found = 1;
            last;
        } else {
            $found = 0;
        }
    }

    # close the file
    if ( close(AUTOHOME) ) {
        logmsg("$name: closed auto.home file $AUTOHOME");
    } else {
        logmsg("$name: FAILED to close auto.home file $AUTOHOME ($!)");
        return(0);
    }

    logmsg("$name: returning with val $found");
    ($found) ? return (1) : return (0);

}

# =============================================================================
# NAME        : _addAutoHome
# DESCRIPTION : Add an auto.home entry for a given user
# REQUIRES    : string(uname), string(homesys), string(rhome)
# RETURNS     : 0 on failure, 1 on success
# NOTES       :
# =============================================================================
sub _addAutoHome {
    fixme("add a test to see if this already exists");
    my ( $uname, $homesys, $rhome ) = @_;
    my $name = "_addAutoHome";
    my ( $package, $filename, $line ) = caller;
    logmsg("$name: entering with args @_");
    logmsg( "$name: called from package->$package, filename->$filename, line->$line" );

    my %ah;

    if ( ! defined($AUTOHOME) ) {
        logmsg("$name: global variable AUTOHOME isn't set");
        return(0);
    }

    fixme("add a test here to see if the existing entry is possibly correct");
    if ( _hasAutoHome($uname) ) {
        logmsg("$name: user $uname already has an entry, perhaps it's correct?");
        return(0);
    }

    if ( open( AUTOHOME, "<$AUTOHOME" ) ) {
        logmsg("$name: opened auto.home file $AUTOHOME for read");
    } else {
        logmsg("$name: FAILED to open auto.home file $AUTOHOME ($!)");
        return(0);
    }

    #   populate %ah with the auto.home entries
    #   Remove all #'s and newlines since they're not supposed to be there
    while (<AUTOHOME>) {
        chomp();
        next if $_ =~ /#/;     # Skip comments
        next if $_ =~ /^$/;    # Skip blank lines

        # Grab the key/value from the input line (whitespace separates the
        # fields)
        my ( $m_uname, $m_mount ) = split( ' ', $_ );
        $ah{$m_uname} = $m_mount;

    }

    # close the file
    if ( close(AUTOHOME) ) {
        logmsg("$name: closed auto.home file $AUTOHOME");
    } else {
        logmsg("$name: FAILED to close auto.home file $AUTOHOME ($!)");
        return(0);
    }

    #
    # Add the new entry
    #
    $ah{$uname} = "$homesys:$rhome/&";

    # open the file for write
    if ( open( AUTOHOME, ">$AUTOHOME" ) ) {
        logmsg("$name: opened auto.home file $AUTOHOME for write");
    } else {
        logmsg("$name: FAILED to open auto.home file $AUTOHOME for write ($!)");
        return(0);
    }

    # lock the file
    if ( flock( AUTOHOME, LOCK_EX ) ) {
        logmsg("$name: placed exclusive lock on auto.home file $AUTOHOME");
    } else {
        logmsg("$name: FAILED to place exclusive lock on auto.home file $AUTOHOME ($!)");
        return(0);
    }

    # Sort the hash by username and print it formatted to the NEW file
    #   - We remove the old file to enforce our formatting and style
    #   - Fields are left justified
    #   - We HAVE to add the trailing & for the automount to work
    #   - Sample:
    #     dyoung2     gsbmba:/export/home/&
    #
    for my $key ( sort keys %ah ) {
        printf AUTOHOME "%-16s %-25s\n", $key, $ah{$key};
    }

    # remove lock from file
    if ( flock( AUTOHOME, LOCK_UN ) ) {
        logmsg("$name: removed lock from auto.home file $AUTOHOME");
    } else {
        logmsg("$name: FAILED to remove lock from auto.home file $AUTOHOME");
        return(0);
    }

    # close the file
    if ( close(AUTOHOME) ) {
        logmsg("$name: closed auto.home file $AUTOHOME");
    } else {
        logmsg("$name: FAILED to close auto.home file $AUTOHOME ($!)");
        return(0);
    }

    return(1);
}

# =============================================================================
# NAME        : delAutoHome
# DESCRIPTION : delete a user's auto.home entry
# REQUIRES    : string(uname)
# RETURNS     : 0 on failure, 1 on success
# NOTES       : See comments for more information
# =============================================================================
sub _delAutoHome ($) {
    my ($uname) = @_;
    my $name = "_delAutoHome";
    my ( $package, $filename, $line ) = caller;
    logmsg("$name: entering with args @_");
    logmsg("$name: called from package->$package, filename->$filename, line->$line");

    my %ah;

    if ( ! defined($AUTOHOME) ) {
        logmsg("$name: FAILED (global variable AUTOHOME isn't set)");
        return(0);
    }

    if ( ! _hasAutoHome($uname) ) {
        logmsg("$name: ** WARNING ** (user doesn't have an entry to delete)");
        ### return(0);
    }

    # Read in the auto.home file and remove the requested entry
    if ( open( AUTOHOME, "<$AUTOHOME" ) ) {
        logmsg("$name: opened auto.home file $AUTOHOME for read");
    } else {
        logmsg("$name: FAILED to open auto.home file $AUTOHOME ($!)" );
        return(0);
    }

    while (<AUTOHOME>) {
        chomp();
        next if $_ =~ /#/;     # Skip comments
        next if $_ =~ /^$/;    # Skip blank lines

        # Grab the key/value from the input line (whitespace separates the
        # fields)
        my ( $m_uname, $m_mount ) = split( ' ', $_ );

        if ( $m_uname eq $uname ) {
            logmsg("$name: removing entry: $m_uname:$m_mount");
            next;
        } else {
            $ah{$m_uname} = $m_mount;
        }

    }

    # close the file from the read
    if ( close(AUTOHOME) ) {
        logmsg("$name: closed auto.home");
    } else {
        logmsg("$name: FAILED to close auto.home ($!)");
        return(0);
    }

    # open the file for write
    if ( open( AUTOHOME, ">$AUTOHOME" ) ) {
        logmsg("$name: opened auto.home file $AUTOHOME for write");
    } else {
        logmsg("$name: FAILED to open auto.home file $AUTOHOME ($!)" );
        return(1);
    }

    # lock the file
    if ( flock( AUTOHOME, LOCK_EX ) ) {
        logmsg("$name: placed exclusive lock on auto.home file $AUTOHOME");
    } else {
        logmsg("$name: FAILED to place exclusive lock on auto.home file $AUTOHOME ($!)");
        return(0);
    }

    # Dump the hash out to a formatted file
    for my $key ( sort keys %ah ) {
        printf AUTOHOME "%-16s %-25s\n", $key, $ah{$key};
    }

    # remove lock from file
    if ( flock( AUTOHOME, LOCK_UN ) ) {
        logmsg("$name: removed lock from auto.home file $AUTOHOME");
    } else {
        logmsg("$name: FAILED to remove lock from auto.home file $AUTOHOME");
        return(0);
    }

    # close the file
    if ( close(AUTOHOME) ) {
        logmsg("$name: closed auto.home file $AUTOHOME");
    } else {
        logmsg("$name: FAILED to close auto.home file $AUTOHOME ($!)");
        return(0);
    }

    return(1);

}

1;
